package org.xiyu.yee.datl.client;

import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.Vec3;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import org.xiyu.yee.datl.config.DatlConfig;

public class ClientTickHandler {
    private static float currentSpinRotation = 0.0f;
    private static boolean wasOnGround = false;
    private static int bhopCooldown = 0;
    private static float originalYaw = 0.0f;
    private static boolean spinningStarted = false;
    
    // CS2风格连跳变量
    private static boolean isBhopping = false;
    private static double currentBhopSpeed = 0.0;
    private static Vec3 lastGroundVelocity = Vec3.ZERO;
    
    public static void onClientTick() {
        Minecraft mc = Minecraft.getInstance();
        if (mc.player == null || mc.level == null) return;
        
        Player player = mc.player;
        DatlConfig config = DatlConfig.getInstance();
        
        // 处理旋转陀螺
        if (config.isSpinEnabled()) {
            if (!spinningStarted) {
                // 记录开始旋转时的原始yaw
                originalYaw = player.getYRot();
                spinningStarted = true;
            }
            
            // 更新旋转角度
            currentSpinRotation = (currentSpinRotation + config.getSpinSpeed()) % 360;
            
            // 发送旋转数据包到服务器（让其他玩家看到旋转）
            sendRotationPacket(player, currentSpinRotation);
        } else {
            if (spinningStarted) {
                // 停止旋转时恢复原始视角
                sendRotationPacket(player, originalYaw);
                spinningStarted = false;
                currentSpinRotation = 0.0f;
            }
        }
        
        // 处理CS2风格连跳
        if (config.isBhopEnabled()) {
            handleCS2Bhop(player);
        } else {
            // 重置连跳状态
            isBhopping = false;
            currentBhopSpeed = 0.0;
        }
        
        // 减少冷却时间
        if (bhopCooldown > 0) {
            bhopCooldown--;
        }
    }
    
    private static void sendRotationPacket(Player player, float yaw) {
        Minecraft mc = Minecraft.getInstance();
        if (mc.getConnection() != null) {
            // 发送旋转数据包，但不影响客户端视角
            mc.getConnection().send(new ServerboundMovePlayerPacket.Rot(
                yaw,
                player.getXRot(),
                player.onGround(),
                player.isShiftKeyDown()
            ));
        }
    }
    
    private static void handleCS2Bhop(Player player) {
        boolean isOnGround = player.onGround();
        Vec3 velocity = player.getDeltaMovement();
        
        // 计算水平速度
        double horizontalSpeed = Math.sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
        
        // 检查玩家是否在移动（W键或方向键）
        boolean isMoving = isPlayerMoving();
        
        if (isOnGround && !wasOnGround) {
            // 刚着地时的处理
            if (isBhopping && isMoving && bhopCooldown == 0) {
                // 计算跳跃时机
                performBhopJump(player, velocity, horizontalSpeed);
                bhopCooldown = 2; // 减少冷却时间，使跳跃更连贯
            } else if (isMoving && horizontalSpeed > 0.1) {
                // 开始连跳序列
                startBhopSequence(player);
                bhopCooldown = 2;
            }
            
            // 记录着地时的速度
            lastGroundVelocity = velocity;
        } else if (!isOnGround && isBhopping) {
            // 空中时的加速处理
            handleAirAcceleration(player, velocity, isMoving);
        }
        
        // 在地面时保持速度（减少摩擦）
        if (isOnGround && isBhopping && isMoving) {
            maintainGroundSpeed(player, velocity, horizontalSpeed);
        }
        
        wasOnGround = isOnGround;
    }
    
    private static boolean isPlayerMoving() {
        Minecraft mc = Minecraft.getInstance();
        if (mc.options == null) return false;
        
        return mc.options.keyUp.isDown() || 
               mc.options.keyDown.isDown() || 
               mc.options.keyLeft.isDown() || 
               mc.options.keyRight.isDown();
    }
    
    private static void startBhopSequence(Player player) {
        DatlConfig config = DatlConfig.getInstance();
        isBhopping = true;
        player.jumpFromGround();
        
        // 给予初始速度提升
        Vec3 velocity = player.getDeltaMovement();
        double currentSpeed = Math.sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
        currentBhopSpeed = Math.max(currentSpeed * config.getBhopInitialBoost(), 0.3);
    }
    
    private static void performBhopJump(Player player, Vec3 velocity, double horizontalSpeed) {
        DatlConfig config = DatlConfig.getInstance();
        
        // 执行跳跃
        player.jumpFromGround();
        
        // 计算速度提升
        double speedBoost = Math.min(horizontalSpeed * config.getBhopSpeedIncrease(), 0.1);
        currentBhopSpeed = Math.min(currentBhopSpeed + speedBoost, config.getBhopMaxSpeed());
        
        // 应用速度提升
        if (horizontalSpeed > 0) {
            double multiplier = currentBhopSpeed / horizontalSpeed;
            player.setDeltaMovement(
                velocity.x * multiplier,
                velocity.y,
                velocity.z * multiplier
            );
        }
    }
    
    private static void handleAirAcceleration(Player player, Vec3 velocity, boolean isMoving) {
        if (!isMoving) return;
        
        DatlConfig config = DatlConfig.getInstance();
        Minecraft mc = Minecraft.getInstance();
        
        // 获取玩家输入方向
        float forward = mc.options.keyUp.isDown() ? 1.0f : (mc.options.keyDown.isDown() ? -1.0f : 0.0f);
        float strafe = mc.options.keyLeft.isDown() ? 1.0f : (mc.options.keyRight.isDown() ? -1.0f : 0.0f);
        
        if (forward == 0 && strafe == 0) return;
        
        // 计算移动方向（相对于玩家朝向）
        float yaw = (float) Math.toRadians(player.getYRot());
        double moveX = -Math.sin(yaw) * forward + Math.cos(yaw) * strafe;
        double moveZ = Math.cos(yaw) * forward + Math.sin(yaw) * strafe;
        
        // 归一化移动向量
        double moveLength = Math.sqrt(moveX * moveX + moveZ * moveZ);
        if (moveLength > 0) {
            moveX /= moveLength;
            moveZ /= moveLength;
        }
        
        // 空中加速度
        double currentSpeed = Math.sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
        double maxSpeed = config.getBhopMaxSpeed();
        
        if (currentSpeed < maxSpeed) {
            double acceleration = config.getBhopAirAcceleration();
            
            // 根据当前速度调整加速度
            if (currentSpeed > 0.5) {
                acceleration *= (maxSpeed - currentSpeed) / maxSpeed;
            }
            
            player.setDeltaMovement(
                velocity.x + moveX * acceleration,
                velocity.y,
                velocity.z + moveZ * acceleration
            );
        }
    }
    
    private static void maintainGroundSpeed(Player player, Vec3 velocity, double horizontalSpeed) {
        DatlConfig config = DatlConfig.getInstance();
        
        // 在地面时减少速度衰减，保持连跳的流畅性
        if (horizontalSpeed > 0.2 && currentBhopSpeed > 0.2) {
            // 应用轻微的速度衰减
            currentBhopSpeed *= config.getBhopSpeedDecay();
            
            // 保持最小速度
            double minSpeed = Math.max(0.2, horizontalSpeed * 0.9);
            if (currentBhopSpeed < minSpeed) {
                currentBhopSpeed = minSpeed;
            }
            
            // 应用速度
            if (horizontalSpeed > 0) {
                double multiplier = currentBhopSpeed / horizontalSpeed;
                player.setDeltaMovement(
                    velocity.x * multiplier,
                    velocity.y,
                    velocity.z * multiplier
                );
            }
        }
    }
    
    public static float getCurrentSpinRotation() {
        return currentSpinRotation;
    }
    
    public static boolean isBhopping() {
        return isBhopping;
    }
    
    public static double getCurrentBhopSpeed() {
        return currentBhopSpeed;
    }
}
